//
//  NSObject+Keyboard.m
//  LinTool
//
//  Created by 林宁宁 on 15/11/12.
//  Copyright © 2015年 000. All rights reserved.
//

#import "NSObject+Keyboard.h"
#import <objc/runtime.h>

@implementation NSObject (Keyboard)



- (NSArray *)ned_KeyboardTargetViews{
    return objc_getAssociatedObject(self, @selector(ned_KeyboardTargetViews));
}

- (void)setNed_KeyboardTargetViews:(NSArray *)ned_KeyboardTargetViews{
    objc_setAssociatedObject(self, @selector(ned_KeyboardTargetViews), ned_KeyboardTargetViews, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIView *)ned_AnimationV{
    return objc_getAssociatedObject(self, @selector(ned_AnimationV));
}

- (void)setNed_AnimationV:(UIView *)ned_AnimationV{
    objc_setAssociatedObject(self, @selector(ned_AnimationV), ned_AnimationV, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}


-(void (^)(CGRect, NSTimeInterval, BOOL))keyBoardAnimationBlock
{
    return objc_getAssociatedObject(self, @selector(keyBoardAnimationBlock));
}


-(void)setKeyBoardAnimationBlock:(void (^)(CGRect, NSTimeInterval, BOOL))keyBoardAnimationBlock
{
    objc_setAssociatedObject(self, @selector(keyBoardAnimationBlock), keyBoardAnimationBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(void (^)(void))completion{
    return objc_getAssociatedObject(self, @selector(completion));
}
-(void)setCompletion:(void (^)(void))completion{
    objc_setAssociatedObject(self, @selector(completion), completion, OBJC_ASSOCIATION_COPY_NONATOMIC);
}



- (void)registerKeyBoardNotifitionWithBlock:(void (^)(CGRect, NSTimeInterval, BOOL))keyBoardAnimationBlock
{
    [self registerKeyBoardNotifitionRemove];
    
    self.keyBoardAnimationBlock = keyBoardAnimationBlock;
    
    // subscribe to keyboard animations
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShowNotification:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHideNotification:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}


-(void)registerKeyBoardNotifitionRemove
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}


#pragma mark private

// ----------------------------------------------------------------
- (void)keyboardWillShowNotification:(NSNotification *)notification {
    [self keyboardWillShowHide:notification isShowing:YES];
}

// ----------------------------------------------------------------
- (void)keyboardWillHideNotification:(NSNotification *)notification {
    [self keyboardWillShowHide:notification isShowing:NO];
}

- (void)keyboardWillShowHide:(NSNotification *)notification isShowing:(BOOL)isShowing {
    // getting keyboard animation attributes
    CGRect keyboardRect = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
    NSTimeInterval duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    
    
    [UIView animateWithDuration:duration
                          delay:0
                        options:UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         [UIView setAnimationCurve:curve];
                         
                         if(self.keyBoardAnimationBlock)
                         {
                             self.keyBoardAnimationBlock(keyboardRect,duration,isShowing);
                         }
                         
                     }
                     completion:^(BOOL finished) {
        
        if(self.completion){
            self.completion();
        }
    }];
}


-(void)ned_keyboardShowAtAnimationView:(UIView *)animationV targetViews:(NSArray<UIView *> *)targetViews completion:(void (^)(void))completion{
    
    self.completion = completion;
    [self ned_keyboardShowAtAnimationView:animationV targetViews:targetViews];
}


-(void)ned_keyboardShowAtAnimationView:(UIView *)animationV targetViews:(NSArray<UIView *> *)targetViews{
    
    self.ned_KeyboardTargetViews = targetViews;
    
    [self ned_keyboardShowAtAnimationView:animationV];
}


-(void)ned_keyboardShowAtAnimationView:(UIView *)animationV{
    
    NSParameterAssert(animationV);
    
    self.ned_AnimationV = animationV;
   
    __weak typeof(&*self)weakSelf = self;
    UIView *(^GetCurrentTargetView)(void) = ^UIView *(void) {
        for(UIView * subV in weakSelf.ned_KeyboardTargetViews){
            if([weakSelf isFirstResponder:subV]){
                return subV;
            }
        }
        if([animationV isKindOfClass:[UITableView class]]){
            UITableView * tableView = (UITableView *)animationV;
            NSArray * list = tableView.visibleCells;
            for(UIView * v in list){
                if([weakSelf isFirstResponder:v]){
                    return v;
                }
            }
            return nil;
        }
        if([animationV isKindOfClass:[UICollectionView class]]){
            UICollectionView * collectionView = (UICollectionView *)animationV;
            NSArray * list = collectionView.visibleCells;
            for(UIView * v in list){
                if([weakSelf isFirstResponder:v]){
                    return v;
                }
            }
            return nil;
        }
        return weakSelf.ned_AnimationV;
    };
    
    [self registerKeyBoardNotifitionRemove];
    
    [self registerKeyBoardNotifitionWithBlock:^(CGRect keyboardRect, NSTimeInterval duration, BOOL isShowing) {
        
        UIView * currentTargetV = GetCurrentTargetView();
        if(!currentTargetV){
            if(!isShowing){
                weakSelf.ned_AnimationV.transform = CGAffineTransformIdentity;
            }
            return;
        }
        
        weakSelf.ned_AnimationV.transform = CGAffineTransformIdentity;
        
        if (isShowing) {

            CGRect targetFrame = currentTargetV.frame;
            if(CGRectIsEmpty(targetFrame)){
                return;
            }
            
            //scrollview 和 targetview是相关联在一起
            if([weakSelf.ned_AnimationV isKindOfClass:[UIScrollView class]]){
                UIScrollView * scrollView = (UIScrollView *)weakSelf.ned_AnimationV;
                CGFloat contentHeight = scrollView.contentSize.height;
                targetFrame.origin.y = MIN(targetFrame.origin.y, contentHeight);
            }
            
            CGRect textFrame = [currentTargetV.superview convertRect:targetFrame toView:[UIApplication sharedApplication].delegate.window];
            
            NSInteger textMaxy = CGRectGetMaxY(textFrame);
            float offset = textMaxy - (CGRectGetMinY(keyboardRect));

            if(offset>0){
                weakSelf.ned_AnimationV.transform = CGAffineTransformMakeTranslation(0, - offset);
            }
        }
    }];
    
}

- (BOOL)isFirstResponder:(UIView *)mainView{
    if(mainView.isFirstResponder){
        return YES;
    }
    for(UIView * subV in mainView.subviews){
        if(subV.isFirstResponder){
            return YES;
        }
        if([self isFirstResponder:subV]){
            return YES;
        }
    }
    return NO;
}

@end
